package com.flanz.apache.velocity.uimocker;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

/**
 * DiscResourceCollector.
 * 
 * @author cf
 * 
 */
public class DiscResourceCollector {

	private File baseDir = null;

	private Map<String, String> virtualResource;

	public Map<String, String> getVirtualResource() {
		return this.virtualResource;
	}

	public void setVirtualResource(final Map<String, String> vr) {
		this.virtualResource = vr;
	}

	public DiscResourceCollector(final String baseDir) {
		this.baseDir = new File(baseDir);
	}

	public Map<String, String> resolveAll() {
		Map<String, String> map = new HashMap<String, String>();
		try {
			File[] listFiles = baseDir.listFiles();
			if (listFiles != null) {
				resolveAll(map, listFiles);
			} else {
				throw new RuntimeException(
						"fail to open artifacts disc files at: "
								+ baseDir.getAbsolutePath());
			}

		} catch (IOException e) {
			throw new RuntimeException("Fail to read from Disc", e);
		}

		addVirtualFiles(map);

		return map;
	}

	private void addVirtualFiles(final Map<String, String> map) {
		if (getVirtualResource() != null) {
			Map<String, String> vr = getVirtualResource();
			Set<String> keySet = vr.keySet();
			for (Iterator<String> iterator = keySet.iterator(); iterator
					.hasNext();) {
				String path = iterator.next();
				map.put(path, vr.get(path));
			}
		}
	}

	private void resolveAll(final Map<String, String> map,
			final File[] listFiles) throws IOException {
		for (int i = 0; i < listFiles.length; i++) {
			File file = listFiles[i];
			if (file.isDirectory()) {
				File[] subListFiles = file.listFiles();
				resolveAll(map, subListFiles);
			} else if (this.accept(file, file.getName())) {
				String payload = FileUtils.readFileToString(file, "UTF-8");
				String makeReleativPath = makeReleativPath(file
						.getAbsolutePath());
				map.put(makeReleativPath, payload);
			}
		}
	}

	/**
	 * MakeReleativPath.
	 * 
	 * @param str
	 * @return
	 */
	private String makeReleativPath(final String absFileName) {
		int length = baseDir.getAbsolutePath().length();
		String result = StringUtils.replaceChars(absFileName, "\\", "//");
		return result.substring(length + 1);
	}

	public boolean accept(final File file, final String arg) {
		return arg.endsWith(".vm") || arg.endsWith(".json");
	}

	public String readFile(final String relPath) {
		String result = null;
		String location = baseDir.getAbsolutePath() + relPath;
		File file = new File(location);
		try {
			result = FileUtils.readFileToString(file, "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
}
